#include <iostream>
#include <string>
#include <sstream>
#include <iterator>
#include <map>
#include <bitset>
#include <vector>
#include <sstream>
#include <algorithm>
#include <functional>
#include <cctype>
#include <cstdlib>
#include <stdio.h>
#include <string.h>



using namespace std;
typedef multimap<short, string> Dict;
typedef map<string, string> Analogus;
typedef pair<string, string> CD;
typedef vector<CD> Cipher;
char mapping[26];
bitset<26> booK_keeping;
Dict Dictionary;
Analogus Analogy;

struct predicate {
	bool operator()( char c ) { return isalpha(c) != 0; }
};

void analogous_code(const string& word, string& code) {
	code.clear();
	string::const_iterator w = word.begin();
	map<char, short> hash;
	map<char, short>::iterator it;
	while(w != word.end()) {
		it = hash.find(*w);
		if(it == hash.end()) {
			pair<char, short>p(*w, 1);
			hash.insert(hash.end(), p);
		} else {
			it->second++;
		}
		w++;
	}
	for(short i =0; i < word.size(); i++) {
			code += hash[word[i]]+'0';
	}
}

bool MAP(const char& c, const char& p) {
	if(mapping[c-'a'] == 0 && booK_keeping.test(p-'a')==false) {
		mapping[c-'a'] = p;
		booK_keeping.set(p-'a');
	}
	return true;
}

struct decipher {
	decipher() {}
	char operator ()(const char& C) {
		return (mapping[C-'a'] == 0 ? '*' : mapping[C-'a']);
	}
	bool operator ()(const char& C, const char& P) {
		return (mapping[C-'a'] == 0 || mapping[C-'a'] == P ? true : false);
	}
};

bool isDecryptable(CD& cipher) {
	pair<Dict::const_iterator, Dict::const_iterator> range = Dictionary.equal_range(cipher.first.size());
	if((range.first == range.second)) return false;
	Dict::const_iterator it = range.first;
	if(Analogy[range.first->second] == cipher.second && ++(it) == range.second) {
		equal(cipher.first.begin(), cipher.first.end(), range.first->second.begin(), MAP);
		return true;
	}
	bool ret = false;
	for(it = range.first; it != range.second; it++) {
		if(Analogy[it->second] == cipher.second) {
			ret = true;
			if(equal(cipher.first.begin(), cipher.first.end(), it->second.begin(), decipher()) == true)	
				equal(cipher.first.begin(), cipher.first.end(), it->second.begin(), MAP);
		}
	}
	return ret;
}

bitset<26> mark;
void Mark(char ch) {
	mark.set(ch-'a');
}

bool decrypt(vector<CD>& line) {
	bool decoded = false;
	mark.reset();
	vector<CD>::iterator it = line.begin();
	while(it != line.end()) {
		for_each(it->first.begin(), it->first.end(), Mark);
		if(isDecryptable(*it) == false) 
			return false;
		it++;
	}
	return (mark.count() == booK_keeping.count());
}


void print_code(const vector<CD> & line) {
	vector<CD>::const_iterator it = line.begin();
	while(it != line.end()) {
		transform(it->first.begin(), it->first.end(), ostream_iterator<char>(cout), decipher());
		it++;
		if(it != line.end())
			cout << " ";
	}
	cout << endl;		
}


CD MakePair(const string& word) {
	string code;
	analogous_code(word, code);
	return CD(word, code);	
}

/* main
 *  * */
int main() {
	short size  = 0;
	memset(mapping, 0, 26);
	string word;
	stringstream tokens;
	cin >> size;
	scanf("%*[^\n]");
	getc(stdin);
	string s;
	while(size-- > 0) {
		tokens.clear();
		getline(cin, s);
		short blankline = count_if(s.begin(), s.end(), predicate());
		if(blankline <= 0) {size++; continue;}
		tokens << s;
		tokens >> word;
		string code;
		analogous_code(word, code);
		pair<short, string> l(word.size(), word);
		Dictionary.insert(Dictionary.end(), l);
		pair<string, string> w(word, code);
		Analogy.insert(Analogy.end(), w);
	}
	Cipher cipher;
	while(true) {
		getline(cin, s);
		if(cin.eof()==true) break;
		short blankline = count_if(s.begin(), s.end(), predicate());
		if(blankline <= 0 || blankline > 100) {cout << endl; continue;}
		tokens.clear();
		cipher.clear();
		booK_keeping.reset();
		tokens << s;
		transform(istream_iterator<string>(tokens), istream_iterator<string>(), back_inserter(cipher), MakePair);
		if(decrypt(cipher) == false) {
			memset(mapping, 0, 26);
			print_code(cipher);
		} else {
			print_code(cipher);
			memset(mapping, 0, 26);
		}
	}
	return 0;
}
